package com.ticket.sass.common.printer.service.impl;

import com.google.gson.Gson;
import com.ticket.sass.common.printer.config.PrinterConfig;
import com.ticket.sass.common.printer.config.YiLianYunPrinterConfig;
import com.ticket.sass.common.printer.dto.AccessTokenResult;
import com.ticket.sass.common.printer.dto.PrintResult;
import com.ticket.sass.common.printer.service.PrinterService;
import com.yly.java.yly_sdk.RequestMethod;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.util.Objects;
import java.util.UUID;

@Service("ylyPrinterService")
public class YiLianYunPrinterService implements PrinterService {
    private final static Logger logger = LoggerFactory.getLogger(PrinterService.class);
    
    private Listener listener;
    
    private YiLianYunPrinterConfig config;
    
    @Override
    public AccessTokenResult print(String content) {
        if (Objects.isNull(config)) {
            logger.info("打印配置未初始化");
            return null;
        }
        AccessTokenResult refreshResult = null;
        try {
            // 初始化请求工具类
            RequestMethod instance = RequestMethod.getInstance();
            
            // 初始化易联云客户端
            instance.init(config.getClientId(), config.getClientSecret());
            
            String accessToken;
            if (config.getToken() != null && !config.getToken().isEmpty()) {
                // 使用配置中的token
                accessToken = config.getToken();
            } else {
                // 获取新的访问令牌
                String refreshResponse = instance.getAccessToken();
                
                // 解析获取的访问令牌响应
                refreshResult = parseAccessTokenResponse(refreshResponse);
                if (!"0".equals(refreshResult.getError())) {
                    // 如果包含错误码，则打印错误信息并返回
                    printErrorMessage(refreshResult, "获取访问令牌失败");
                    if (listener != null) {
                        // 刷新token失败回调
                        listener.onRefreshAccessTokenFail(refreshResponse);
                    }
                    return refreshResult;
                }
                
                accessToken = refreshResult.getBody().getAccessToken();
                if (listener != null) {
                    listener.onRefreshAccessToken(accessToken);
                }
            }
            
            // 获取打印机编号
            String machineCode = config.getMachineCode();
            
            // 调用打印方法
            String printResponse = instance.printIndex(accessToken, machineCode, content, UUID.randomUUID().toString());
            
            // 解析打印响应
            PrintResult printResult = parseResponse(printResponse);
            if (!"0".equals(printResult.getError())) {
                // 如果包含错误码，则打印错误信息并返回
                printErrorMessage(printResult, "打印文本失败");
                if (listener != null) {
                    listener.onFail(printResult);
                }
            } else {
                logger.info("打印文本返回: {}", printResponse);
                if (listener != null) {
                    listener.onSuccess(printResult);
                }
            }
            
            // 返回刷新后的token
            return refreshResult;
        } catch (Exception e) {
            // 异常处理
            e.printStackTrace();
            return null;
        }
    }
    
    @Override
    public <U extends PrinterConfig> void setConfig(U printerConfig) {
        config = (YiLianYunPrinterConfig) printerConfig;
    }
    
    @Override
    public <U extends PrinterService.Listener> void setLister(U listener) {
        this.listener = listener;
    }
    
    // 解析 JSON 响应
    private AccessTokenResult parseAccessTokenResponse(String jsonResponse) {
        return new Gson().fromJson(jsonResponse, AccessTokenResult.class);
    }
    
    // 解析 JSON 响应
    private PrintResult parseResponse(String jsonResponse) {
        return new Gson().fromJson(jsonResponse, PrintResult.class);
    }
    
    // 打印错误信息
    private void printErrorMessage(AccessTokenResult result, String message) {
        String errorCode = result.getError();
        String errorDescription = result.getErrorDescription();
        String errorBody = result.getBody() != null ? result.getBody().toString() : "无";
        logger.error("{}：错误码 {}，错误描述：{}，错误主体：{}", message, errorCode, errorDescription, errorBody);
    }
    
    // 打印错误信息
    private void printErrorMessage(PrintResult result, String message) {
        String errorCode = result.getError();
        String errorDescription = result.getErrorDescription();
        String errorBody = result.getBody() != null ? result.getBody().toString() : "无";
        logger.error("{}：错误码 {}，错误描述：{}，错误主体：{}", message, errorCode, errorDescription, errorBody);
    }
}
